package com.xayy.health.mgt.service.impl;

import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpStatus;
import cn.hutool.http.Method;
import cn.kawins.base.utils.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xayy.health.core.config.param.YcParam;
import com.xayy.health.core.enums.ModuleEnum;
import com.xayy.health.mgt.service.FaultReportService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.lang.management.ManagementFactory;
import java.lang.management.OperatingSystemMXBean;
import java.lang.management.RuntimeMXBean;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Date;
import java.util.EnumSet;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;


/**
 * @author zhangx
 */
@Service
public class FaultReportServiceImpl implements FaultReportService {

    @Autowired
    private YcParam ycParam;

    @Override
    public void faultReport(String moduleId, String module, String faultName, String reason) throws UnknownHostException {
        String ip = InetAddress.getLocalHost().getHostAddress();
        String uuid = UUID.randomUUID().toString().substring(0, 12);
        String systemId = "dsj-wxjk-xayy";
        RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean();
        String progress = runtimeMXBean.getName();
        String progressId = progress.split("@")[0];
        JSONObject parms = new JSONObject();
        //系统名
        parms.put("system", "卫星健康管理辅助决策");
        //系统编号
        parms.put("systemId", systemId);
        //模块名
        parms.put("module", module);
        //模块编号
        parms.put("moduleId", moduleId);
        //进程名
        parms.put("progressName", progress);
        //部署位置
        parms.put("deploymentLlocation", "k8s");
        //故障编号
        parms.put("faultId", systemId + moduleId + progressId + uuid);
        //故障名称
        parms.put("faultName", faultName);
        //故障时间
        parms.put("faultTime", new Date());
        //用户终端
        parms.put("userTerminal", ip);
        //故障原因
        parms.put("reason", reason);
        //故障描述
        parms.put("desc", reason);
        //故障消除方法
        parms.put("eliminationMethod", "请联系管理员");
        HttpResponse getResponse = HttpUtil.createRequest(Method.POST, ycParam.getYcFaultInformation()).body(parms.toString()).timeout(600000).execute();
        if (getResponse.getStatus() != HttpStatus.HTTP_OK) {
            throw new RuntimeException("调用故障信息上报接口异常");
        }
    }

    @Override
    public void progressStatus() throws UnknownHostException {
        System.out.println("****************************开始上报****************************");
        String ip = InetAddress.getLocalHost().getHostAddress();
        RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean();
        String progress = runtimeMXBean.getName();
        String progressId = progress.split("@")[0];
        //cpu和内存使用情况
        OperatingSystemMXBean operatingSystemMXBean = ManagementFactory.getOperatingSystemMXBean();
        String osJson = JSON.toJSONString(operatingSystemMXBean);
        JSONObject jsonObject = JSON.parseObject(osJson);
        double systemCpuLoad = jsonObject.getDouble("systemCpuLoad") * 100;
        Long totalPhysicalMemorySize = jsonObject.getLong("totalPhysicalMemorySize");
        Long freePhysicalMemorySize = jsonObject.getLong("freePhysicalMemorySize");
        double memoryUseRatio = 1.0 * (totalPhysicalMemorySize - freePhysicalMemorySize) / totalPhysicalMemorySize * 100;
        List<ModuleEnum> moduleEnumList = EnumSet.allOf(ModuleEnum.class)
                .stream()
                .collect(Collectors.toList());
        moduleEnumList.forEach(moduleEnum -> {
            String moduleName = moduleEnum.getMsg();
            String moduleCode = moduleEnum.getCode();
            System.out.println(moduleName + "****************************开始上报****************************");
            JSONObject parms = new JSONObject();
            //系统名
            parms.put("system", "卫星健康管理辅助决策");
            //模块名
            parms.put("module", moduleName);
            //模块名id
            parms.put("moduleId", moduleCode);
            //部署位置
            parms.put("deploymentLlocation", "k8s");
            //进程位置的ip
            parms.put("progressIp", ip);
            //进程名
            parms.put("progressName", progress);
            //进程代号
            parms.put("progressCode", progressId);
            //启动时间
            parms.put("runUpTime", runtimeMXBean.getStartTime());
            //进程状态
            parms.put("status", "正常");
            //cpu占用率
            parms.put("cpuUtility", twoDecimal(systemCpuLoad) + "%");
            //内存占用率
            parms.put("memoryUsage", twoDecimal(memoryUseRatio)+ "%");
            //运行时间长
            parms.put("runningTime", getSystemUptime());
            HttpResponse getResponse = HttpUtil.createRequest(Method.POST, ycParam.getYcProgressStatus()).body(parms.toString()).timeout(600000).execute();
            if (getResponse.getStatus() != HttpStatus.HTTP_OK) {
                throw new RuntimeException("调用进程状态接口异常");
            }
        });

    }

    public String twoDecimal(double doubleValue) {
        BigDecimal bigDecimal = new BigDecimal(doubleValue).setScale(2, RoundingMode.HALF_UP);
        return bigDecimal.toString();
    }


    private static String getSystemUptime() {
        RuntimeMXBean runtimeBean = ManagementFactory.getRuntimeMXBean();
        long startTime = runtimeBean.getStartTime();
        long currentTime = System.currentTimeMillis();
        long time = (currentTime - startTime) / 1000;
        BigDecimal timeBigDecimal = new BigDecimal(time);
        String secondsTime = formatSecondsTime(timeBigDecimal);
        return secondsTime; // 转换为秒
    }

    /**
     * 格式化秒单位为 毫秒 秒 分 时 天
     * @param seconds
     * @return
     */
    public static String formatSecondsTime(BigDecimal seconds) {
        if (seconds == null || seconds.compareTo(BigDecimal.ZERO) == 0) {
            return "0毫秒";
        }
        BigDecimal milliseconds = seconds.multiply(BigDecimal.valueOf(1000)).setScale(0, RoundingMode.DOWN);

        BigDecimal ss = BigDecimal.valueOf(1000);
        BigDecimal mi = ss.multiply(BigDecimal.valueOf(60));
        BigDecimal hh = mi.multiply(BigDecimal.valueOf(60));
        BigDecimal dd = hh.multiply(BigDecimal.valueOf(24));

        BigDecimal day = milliseconds.divide(dd, 0, RoundingMode.DOWN);
        milliseconds = milliseconds.remainder(dd);

        BigDecimal hour = milliseconds.divide(hh, 0, RoundingMode.DOWN);
        milliseconds = milliseconds.remainder(hh);

        BigDecimal minute = milliseconds.divide(mi, 0, RoundingMode.DOWN);
        milliseconds = milliseconds.remainder(mi);

        BigDecimal second = milliseconds.divide(ss, 0, RoundingMode.DOWN);
        milliseconds = milliseconds.remainder(ss);

        StringBuilder sb = new StringBuilder();
        if (day.compareTo(BigDecimal.ZERO) > 0) {
            sb.append(day).append("天");
        }
        if (hour.compareTo(BigDecimal.ZERO) > 0) {
            sb.append(hour).append("时");
        }
        if (minute.compareTo(BigDecimal.ZERO) > 0) {
            sb.append(minute).append("分");
        }
        if (second.compareTo(BigDecimal.ZERO) > 0) {
            sb.append(second).append("秒");
        }
        if (milliseconds.compareTo(BigDecimal.ZERO) > 0) {
            sb.append(milliseconds).append("毫秒");
        }
        return sb.toString();
    }


}


